package com.zty.tool;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 线程池优雅关闭
 *
 * @author: zty
 * @date: 2023/1/15
 */
@Slf4j
public class ThreadPoolUtils {

    private ThreadPoolUtils() {
    }

    /**
     * @param pool               要关闭的线程池
     * @param shutdownTimeout    shutdown的可等待时间 超过这个时间便执行pool.shutdownNow();
     * @param shutdownNowTimeout 最大忍耐时间，超过这个时间便执报错;
     * @param timeUnit           时间单位
     */
    public static void shutdownPool(ExecutorService pool,
                                    int shutdownTimeout,
                                    int shutdownNowTimeout,
                                    TimeUnit timeUnit) {
        //  柔性关闭
        pool.shutdown();
        try {
            //  若shutdown后等待了shutdownTimeout时间仍未关闭
            if (!pool.awaitTermination(shutdownTimeout, timeUnit)) {
                //  执行shutdownNow，暴力关闭
                pool.shutdownNow();

                //  强行关闭等待shutdownNowTimeout后仍为关闭成功
                if (!pool.awaitTermination(shutdownNowTimeout, timeUnit)) {
                    log.error("com.zty.tool.ThreadPoolUtils.shutdownPool.error");
                }
            }
        } catch (InterruptedException ie) {
            //  若调用此工具类的线程被打断了（挂掉了）
            //  报错打日志
            log.error("com.zty.tool.ThreadPoolUtils.shutdownPool.interrupted.error:{}", ie.getMessage(), ie);
            //  直接暴力关闭
            pool.shutdownNow();
            //  将线程的标志位设为打断
            Thread.currentThread().interrupt();
        }
    }

}
